//use cxx::let_cxx_string;

pub struct MultiBuf {
    chunks: Vec<Vec<u8>>,
    pos: usize,
}

#[cxx::bridge]
mod ffi {
    struct BlobMetadata{
        size: usize,
        tags: Vec<String>,
    }

    extern "Rust" {
        type MultiBuf;

        fn next_chunk(buf: &mut MultiBuf) -> &[u8];
    }

    unsafe extern "C++" {
        include!("rust_cxx_demo/librscxx/rscxx.h");

        #[cxx_name = "RsCxxCls"]
        type RsCxx;

        fn isNull(self: &RsCxx) -> bool;
        fn isString(self: &RsCxx) -> bool;
        fn getNumber(self: &RsCxx) -> f64;
        fn getString(self: &RsCxx) -> UniquePtr<CxxString>;
        //fn getVector(self: &RsCxx) -> &CxxVector<CxxString>;

        fn put(&self, buf: &mut MultiBuf) -> i32;

        fn tag(&self, id: i32, tag: &str);
        fn metadata(&self, id: i32) -> BlobMetadata;

        fn getRsCxx() -> UniquePtr<RsCxx>;
    }
}

pub fn next_chunk(buf: &mut MultiBuf) -> &[u8] {
    let next = buf.chunks.get(buf.pos);
    buf.pos += 1;
    next.map_or(&[], Vec::as_slice)
}

pub fn get_string() -> String {
    let rs_cxx = ffi::getRsCxx();
    println!("{} [{}] {} {}", rs_cxx.getNumber(), rs_cxx.getString(), rs_cxx.isNull(), rs_cxx.isString());

    let chunks = vec![b"fearless".to_vec(), b"hello".to_vec()];
    let mut buf = MultiBuf {chunks, pos: 0};
    let id = rs_cxx.put(&mut buf);
    println!("id = {}", id);

    rs_cxx.tag(id, "rust hello");

    let metadata = rs_cxx.metadata(id);
    println!("tags = {:?}", metadata.tags);

    String::from("test")
}

